package com.wtwd.campus.jdzc.controller;

import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.entity.Alarm;
import com.wtwd.campus.entity.AlarmVO;
import com.wtwd.campus.entity.DeviceAlarm;
import com.wtwd.campus.jdzc.common.Constant;
import com.wtwd.campus.jdzc.common.RespCode;
import com.wtwd.campus.jdzc.common.RespEntity;
import com.wtwd.campus.jdzc.entity.DeviceInfo;
import com.wtwd.campus.jdzc.service.AuthService;
import com.wtwd.campus.jdzc.service.JdzcDeviceAlarmService;
import com.wtwd.campus.jdzc.service.JdzcDeviceInfoService;
import com.wtwd.campus.jdzc.service.JdzcUserStudentPermissionService;
import com.wtwd.campus.service.RedisService;
import com.wtwd.campus.utils.CommandSendUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: ldaoliang
 * @DateTime: 2022/2/14 16:33
 * @Description:
 */
@RestController
@RequestMapping("/jdzc/clock")
public class JdzcClockController {

    private static final Logger logger = LoggerFactory.getLogger(JdzcClockController.class);

    @Autowired
    private JdzcDeviceInfoService deviceInfoService;

    @Autowired
    private JdzcDeviceAlarmService jdzcDeviceAlarmService;

    @Autowired
    private AuthService authService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private JdzcUserStudentPermissionService jdzcUserStudentPermissionService;

    @Autowired
    private CommandSendUtils commandSendUtils;


    /**
     * 查询学生的闹钟信息
     */
    @GetMapping("/getAlarmMess/{stuId}")
    public RespEntity getAlarmMess(@PathVariable("stuId") Integer stuId, HttpServletRequest request) {
        logger.info("/getAlarmMess : stuId = {} ", stuId.toString());
        Integer userId = getUserId(request);
        if (userId==null){
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Boolean authStudent = authService.authStudent(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        Map<String, Object> result = new HashMap<>();
        //首先判断设备是否是有屏幕
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.STUDENT_NOT_BIND_DEVICE);
        }
        /*if (deviceInfo.getIfScreen() == null || deviceInfo.getIfScreen() != 1) {
            List<Alarm> list2=new ArrayList<>();
            result.put("if_screen", false);
            result.put("data", list2);
            return new RespEntity(RespCode.SUCCESS, result);
        } else {
            result.put("if_screen", true);
        }*/
        result.put("if_screen", true);
        //有屏幕则查找闹钟信息
        List<Alarm> alarmList = jdzcDeviceAlarmService.getAlarmListByDeviceId(deviceInfo.getDeviceId());
        //如果是一次性且开启的闹钟，还需要判断是否已经响过了，如果已经响过了则关闭（只是数据库关闭）
        alarmList.stream().forEach(e -> {
            String repeatTime = e.getRepeatTime();
            if ("0000000".equals(repeatTime) && e.getFlag() == 1) {
                Long createTime = e.getCreateTime();
                String time = e.getTime();
                boolean b = judgeIfAlarm(createTime, time);
                if (b) {
                    //已经响过了，则关闭
                    e.setFlag(0);
                    //修改数据库数据
                    jdzcDeviceAlarmService.closeAlarmById(e.getId(), 0);
                }
            }
        });
        result.put("data", alarmList);
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 添加闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addAlarm")
    public RespEntity addAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/addAlarm :userId={},data={}", userId.toString(), data.toString());
        //校验学生是否可操作
        Boolean authStudent = authService.authStudent(data.getStuId(), Constant.jdzcOrgCode, userId);
        if (!authStudent){
         return new RespEntity(RespCode.NO_PERMISSION);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(data.getStuId(), userId);
        //获取一个可用序列号
        Integer sequence = getAlarmSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.ALARM_HAD_FULL);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            Integer flag = 1;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(flag);
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(sequence);
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //添加一个闹钟
                Alarm alarm = new Alarm();
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_ADD);
                alarm.setFlag(flag);
                alarm.setRepeatTime(data.getRepeat());
                alarm.setDeviceId(deviceInfo.getDeviceId());
                alarm.setName(data.getName());
                alarm.setTime(data.getTime());
                alarm.setSequence(sequence);
                int i = jdzcDeviceAlarmService.addAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 修改闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifyAlarm")
    public RespEntity modifyAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/modifyAlarm :userId={},data={}", userId.toString(), data.toString());
        //校验学生是否可操作
        Boolean authStudent = authService.authStudent(data.getStuId(), Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(data.getStuId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(data.getStuId(), userId);
        //获取闹钟信息
        Alarm alarm = jdzcDeviceAlarmService.queryAlarmById(data.getId());
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(alarm.getFlag());
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改一个闹钟
                alarm.setTime(data.getTime());
                alarm.setName(data.getName());
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setRepeatTime(data.getRepeat());
                int i = jdzcDeviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除一个闹钟
     *
     * @param stuId
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/deleteAlarm/{stuId}/{id}")
    public RespEntity deleteAlarm(@PathVariable("stuId") Integer stuId, @PathVariable("id") Integer id, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /* Integer userId = 3;*/
        logger.info("/deleteAlarm :stuId={},id={}", stuId.toString(), id.toString());
        //校验学生是否可操作
        Boolean authStudent = authService.authStudent(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(stuId, userId);
        //获取闹钟信息
        Alarm alarm = jdzcDeviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            JSONObject data = new JSONObject();
            data.put("imei", deviceInfo.getImei());
            data.put("commandNumber", commandNumber);
            data.put("sequence", alarm.getSequence());
            boolean b1 = commandSendUtils.deleteAlarm(data, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改闹钟的状态为待删除
                alarm.setStatus(Constants.DEVICE_ALARM_DELETE);
                alarm.setCommandNumber(commandNumber);
                int i = jdzcDeviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 开启关闭闹钟
     */
    @GetMapping("/openOrCloseAlarm/{stuId}/{id}/{flag}")
    public RespEntity openOrCloseAlarm(@PathVariable("stuId") Integer stuId, @PathVariable("id") Integer id
            , @PathVariable("flag") Integer flag, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/openOrCloseAlarm : stuId = {} ,id={},flag={}", stuId.toString(), id.toString(), flag.toString());
        //校验学生是否可操作
        Boolean authStudent = authService.authStudent(stuId, Constant.jdzcOrgCode, userId);
        if (!authStudent){
            return new RespEntity(RespCode.NO_PERMISSION);
        }
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByStuId(stuId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        Alarm alarm = jdzcDeviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        boolean b = veryAuthentication(stuId, userId);
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            int realFlag = 0;
            realFlag = flag == 0 ? 1 : 0;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(realFlag);
            deviceAlarm.setName(alarm.getName());
            deviceAlarm.setRepeatTime(alarm.getRepeatTime());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(alarm.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.WX_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改数据库信息
                alarm.setFlag(realFlag);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCommandNumber(commandNumber);
                if (realFlag == 1 && "0000000".equals(alarm.getRepeatTime())) {
                    alarm.setCreateTime(System.currentTimeMillis());
                }
                int i = jdzcDeviceAlarmService.modifyAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 根据id获取一个闹钟的信息
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getAlarmById/{id}")
    public RespEntity getAlarmById(@PathVariable("id") Integer id, HttpServletRequest request) {
        logger.info("/getAlarmById :id={}", id.toString());
        Alarm alarm = jdzcDeviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        return new RespEntity(RespCode.SUCCESS, alarm);
    }



    /**
     * 判断操作的家长是否是学生的主监护人
     *
     * @param stuId
     * @param userId
     * @return
     */
    public boolean veryAuthentication(Integer stuId, Integer userId) {
       /* //根据学生id查找学生信息
        Map<String, Object> student = studentService.getStudentByStuId(stuId);
        //根据微信用户id查询用户电话号码
        String number = deviceWhiteListService.getNumberByWXUserId(userId);
        if (number == null || !((String) student.get("parent_phone")).equals(number)) {
            return false;
        }
        return true;*/
        //根据学生id和用户id查询一条绑定记录
        Map<String, Object> map = jdzcUserStudentPermissionService.getBindingByStuIdAndUserId(stuId, userId);
        Integer isAuthorization = (Integer) map.get("is_authorization");
        if (isAuthorization == null) {
            return false;
        }
        return isAuthorization == 1 ? true : false;
    }


    /**
     * 获取用户id
     *
     * @param request
     * @return
     */
    public Integer getUserId(HttpServletRequest request) {
        //获取用户id
        String token = request.getHeader(Constant.HEADER_TOKEN_KEY);
        if (token.equals("aaab")) {
            return 3;
        }
        String redisUserId = redisService.getValue(token);
        if (StringUtils.isBlank(redisUserId)) {
            return 0;
        }
        Integer userId = Integer.parseInt(redisUserId);
        return userId;
    }



    /**
     * 判断一次性闹钟是否已经响过了
     *
     * @param createTime
     * @param time
     * @return
     */
    public static boolean judgeIfAlarm(Long createTime, String time) {
        //根据创建时间和设置时间，算出第一次响铃时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(createTime);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        String minuteStr = minute < 10 ? "0".concat(String.valueOf(minute)) : String.valueOf(minute);
        String oldTime = String.valueOf(hour).concat(":").concat(minuteStr);
        String[] split = time.split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
        calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
        Long firstAlarm = 0l;
        if (time.compareTo(oldTime) >= 0) {
            //说明第一次铃响跟创建闹钟是在同一天
            firstAlarm = calendar.getTimeInMillis();
        } else {
            //说明第一次响铃是创建闹钟的后一天
            createTime = createTime + 24 * 60 * 60 * 1000;
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTimeInMillis(createTime);
            calendar2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
            calendar2.set(Calendar.MINUTE, Integer.valueOf(split[1]));
            firstAlarm = calendar2.getTimeInMillis();
        }
        return System.currentTimeMillis() > firstAlarm ? true : false;
    }



    /**
     * 获取一个闹钟的可用的序列号
     *
     * @param deviceId
     * @return
     */
    public Integer getAlarmSequence(Integer deviceId) {
        //获取该设备已经存在的课堂模式
        List<Alarm> list = jdzcDeviceAlarmService.getAlarmListByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (Alarm alarm : list) {
            seqList.add(alarm.getSequence());
        }
        for (int i = 1; i <= 10; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }


    /**
     * 判断设备是否在线
     *
     * @param imei 设备imei号
     * @return 设备是否在线
     */
    public boolean deviceOnline(String imei) {
        boolean isOnline = redisService.hasKey(Constants.DEVICE_ONLINE_PREFIX + imei);
        logger.info("设备:【{}】: {}", imei, isOnline ? "在线" : "离线");
        return isOnline;
    }

    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }

}
